package com.yuqiao.read.lambda;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.DoubleUnaryOperator;
import java.util.stream.IntStream;
import java.util.stream.LongStream;

public class LambadTest {
    public static void main(String[] args) {
//        BigDecimal b1 = new BigDecimal("0.91");
//        BigDecimal b2 = new BigDecimal("0.10");
//        BigDecimal b3 = new BigDecimal("0.09");
//        BigDecimal b4 = new BigDecimal("0.01");
//        BigDecimal b5 = new BigDecimal("1.99");
//        BigDecimal b6 = new BigDecimal("1.00");
//        BigDecimal b7 = new BigDecimal("7.1");
//        BigDecimal b8 = new BigDecimal(7.9);
//        System.out.println(b1.multiply(new BigDecimal("100")).intValue());
//        System.out.println(b2.multiply(new BigDecimal("100")).intValue());
//        System.out.println(b3.multiply(new BigDecimal("100")).intValue());
//        System.out.println(b4.multiply(new BigDecimal("100")).intValue());
//        System.out.println(b5.multiply(new BigDecimal("100")).intValue());
//        System.out.println(b6.multiply(new BigDecimal("100")).intValue());
//        System.out.println(b7.multiply(new BigDecimal("100")).intValue());
//        System.out.println(b8.multiply(new BigDecimal("100")).intValue());
//        System.out.println(6*100);


//        List<Integer> list = new ArrayList<>();
//        list.add(1);
//        list.add(4);
//        list.add(9);
//
//        List<List<Integer>> subsets = subsets(list);
//
//        for (List<Integer> list1 : subsets) {
//             System.out.println(list1);
//        }
//        System.out.println(factorialJava8(10000000));
//        System.out.println(factorialIterrative(10000000));
//        System.out.println(factoriallTailRecursive(10000000));

//        DoubleUnaryOperator convertCtoF = curriedConverter(9.0 / 5, 32);
//        double v = convertCtoF.applyAsDouble(0);
//        System.out.println(v);
//        System.out.println(factorialRecursive(10000000));
        IntStream numbers = numbers();
        IntStream primes = primes(numbers);
//        int head = head(numbers);
//        IntStream filtered = tail(numbers).filter(n -> n % head != 0);


    }

    static List<List<Integer>> subsets(List<Integer> list) {
        if (list.isEmpty()) {
            List<List<Integer>> ans = new ArrayList<>();
            ans.add(Collections.emptyList());
            return ans;
        }
        Integer first = list.get(0);
        List<Integer> rest = list.subList(1, list.size());
        List<List<Integer>> subans = subsets(rest);
        List<List<Integer>> subans2 = insertAll(first, subans);
        return caoncat(subans, subans2);
    }

    static List<List<Integer>> insertAll(Integer first, List<List<Integer>> lists) {
        List<List<Integer>> result = new ArrayList<>();
        for (List<Integer> list : lists) {
            List<Integer> copyList = new ArrayList<>();
            copyList.add(first);
            copyList.addAll(list);
            result.add(copyList);
        }
        return result;
    }


    static List<List<Integer>> caoncat(List<List<Integer>> list1, List<List<Integer>> list2) {
        List<List<Integer>> r = new ArrayList<>(list1);
        r.addAll(list2);
        return r;
    }


    static long factorialIterrative(int n) {
        int r = 1;
        for (int i = 1; i <= n; i++) {
            r *= i;
        }
        return r;
    }

    static long factorialRecursive(int n) {
        return n == 1 ? 1 : n * factorialRecursive(n - 1);
    }

    static long factorialJava8(int n) {
        return LongStream.rangeClosed(1, n)
                .reduce(1, (long a, long b) -> a * b);
    }


    static long factoriallTailRecursive(long n) {
        return factoriallHelper(1, n);
    }

    static long factoriallHelper(long acc, long n) {
        return n == 1 ? acc : factoriallHelper(acc * n, n - 1);
    }


    static double converter(double x, double f, double b) {
        return x * f + b;
    }

    /**
     * 科里化
     *
     * @param f
     * @param b
     * @return
     */
    static DoubleUnaryOperator curriedConverter(double f, double b) {
        return (double x) -> x * f + b;
    }

    /**
     * 构造由数字组成的stream
     * @return
     */
    static IntStream numbers(){
        return IntStream.iterate(2,n-> n+1);
    }

    /**
     * 取得首元素
     * @param numbers
     * @return
     */
    static int head(IntStream numbers){
        return numbers.findFirst().getAsInt();
    }

    /**
     * 对尾部元素进行筛选
     * @param numbers
     * @return
     */
    static IntStream tail(IntStream numbers){
        return numbers.skip(1);
    }

    static IntStream primes(IntStream numbers){
        int head = head(numbers);
        return IntStream.concat(
                IntStream.of(head),
                primes(tail(numbers).filter(n -> n % head != 0))
        );
    }
}

//class Tree {
//    private String key;
//    private int value;
//    private Tree left, right;
//
//    public Tree(String k, int v, Tree l, Tree r) {
//        key = k;
//        value = v;
//        left = l;
//        right = r;
//    }
//}
//class TreeProcessor{
//    public static int lookup(String k,int defaultval,Tree t){
//        if(t == null){
//            return defaultval;
//        }
////        if(k.equals(t.key))
//    }
//}

